package com.sh.d1.gameserver;

import com.google.protobuf.Message;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 游戏消息解码器
 */
public class GameMsgEncoder extends ChannelOutboundHandlerAdapter {
    /**
     * 日志对象
     */
    static private final Logger LOGGER = LoggerFactory.getLogger(GameMsgEncoder.class);

    @Override
    public void write(ChannelHandlerContext ctx, Object msgObj, ChannelPromise promise) throws Exception {
        if (!(msgObj instanceof InternalServerMsg)) {
            super.write(ctx, msgObj, promise);
            return;
        }

        InternalServerMsg innerMsg = (InternalServerMsg) msgObj;
        Message resultMsg = innerMsg.getMsgObj();

        if (null == resultMsg) {
            return;
        }

        // 获取消息类
        Class<?> resultMsgClazz = resultMsg.getClass();
        // 获取消息编号
        int msgCode = GameMsgRecognizer.getMsgCodeByMsgType(resultMsgClazz);

        if (msgCode < 0) {
            LOGGER.error(
                "获取消息编号失败, resultMsgClazz = {}",
                resultMsgClazz.getName()
            );
            return;
        }

        byte[] msgBody = resultMsg.toByteArray();

        ByteBuf byteBuf = ctx.alloc().buffer();
        byteBuf.writeShort(0); // 写出消息长度, 默认 = 0, 先占个位置
        byteBuf.writeInt(innerMsg.getGatewayServerId()); // 写出网关服务器 Id
        byteBuf.writeInt(innerMsg.getRemoteSessionId()); // 写出远程服务器会话 Id
        byteBuf.writeInt(innerMsg.getFromUserId()); // 写出来自用户 Id
        byteBuf.writeShort(msgCode); // 写出消息编号
        byteBuf.writeBytes(msgBody); // 写出消息体

        // 更新消息长度
        byteBuf.setShort(0,byteBuf.readableBytes() - 2);

        BinaryWebSocketFrame outputFrame = new BinaryWebSocketFrame(byteBuf);
        super.write(ctx, outputFrame, promise);
    }
}
